home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
admin
/
linuxcon.000
/
linuxcon
/
linuxconf-1.6
/
netconf
/
datetime.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-30
|
7KB
|
265 lines
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include "netconf.h"
#include "internal.h"
#include "../userconf/userconf.h"
#include "../fstab/fstab.h"
#include "netconf.m"
static const char DATETIME_P[]="datetime";
static const char UNIVERSAL[]="universal";
static const char NETDATE[]="netdate";
static NETCONF_HELP_FILE help_date ("datetime");
PUBLIC DATETIME::DATETIME()
{
universal = linuxconf_getvalnum (DATETIME_P,UNIVERSAL,0);
netdate.setfrom (linuxconf_getval (DATETIME_P,NETDATE));
}
PUBLIC void DATETIME::save()
{
linuxconf_replace (DATETIME_P,UNIVERSAL,universal);
linuxconf_replace (DATETIME_P,NETDATE,netdate);
linuxconf_save();
}
/*
Extract recursivly a directory, getting all files.
tbf will contain the path relative to a certain path (using
skip_prefix to strip the beginning).
*/
static void datetime_zonelst (
int skip_prefix,
SSTRINGS &tbf,
const char *path)
{
/* #Specification: netconf / datetime / zoneinfo / options
netconf finds the possible time zone available by listing
the content of the directory /usr/lib/zoneinfo. It does it
recursivly. It avoid symbolic links and executable file.
The file "time.doc" is also removed explicitly since many
slackware do contain it.
*/
int start = tbf.getnb();
dir_getlist (path,tbf);
int end = tbf.getnb();
for (int i=start; i<end; i++){
char fpath[PATH_MAX];
SSTRING *str = tbf.getitem(i);
const char *pt = str->get();
sprintf (fpath,"%s/%s",path,pt);
struct stat st;
char *replace = "";
if (lstat (fpath,&st)!=-1){
if (S_ISDIR(st.st_mode)){
if (strcmp(pt,".")!=0
&& strcmp(pt,"..")!=0){
datetime_zonelst (skip_prefix
,tbf,fpath);
}
}else if(S_ISREG(st.st_mode)
&& strcmp(pt,"time.doc")!=0
&& ! (st.st_mode & 0100)){
// As you see, we only collect regular
// file. All others (directories, special
// files or files that can't be stat will
// be thrown away.
replace = fpath+skip_prefix;
}
}
str->setfrom(replace);
}
}
static void datetime_zonelst (FIELD_COMBO *comb)
{
SSTRINGS tbf;
datetime_zonelst (strlen(USR_LIB_ZONEINFO)+1
,tbf,USR_LIB_ZONEINFO);
tbf.sort();
int nb = tbf.getnb();
for (int i=0; i<nb; i++){
const char *pt = tbf.getitem(i)->get();
if (pt[0] != '\0') comb->addopt (pt);
}
}
/*
Get or set the current zoneinfo by reading the symbolic link
/usr/lib/zoneinfo/localtime.
*/
static void datetime_getsetcurzone(SSTRING &str)
{
/* #Specification: netconf / datetime / zoneinfo / current
netconf finds out the current zone by looking at the
symbolic links /usr/lib/zoneinfo/localtime.
It will follow this link up to five time.
When setting the new time zone, it will also follows
the links and redo only the last one. The idea here is
that it support both strategy
#
ln -sf /usr/lib/zoneinfo/country/value /usr/lib/zoneinfo/localtime
#
and
#
ln -sf /usr/lib/zoneinfo/country/value /var/lib/zoneinfo/localtime
ln -sf /var/lib/zoneinfo/localtime /usr/lib/zoneinfo/localtime
#
The later being more "correct" fsstnd wise.
*/
int iter = 0;
char path[PATH_MAX];
strcpy (path,USR_LIB_LOCALTIME);
while (iter < 5){
char buf[PATH_MAX];
int nb = readlink (path,buf,sizeof(buf)-1);
if (nb != -1){
buf[nb] = '\0';
struct stat st;
if (lstat(buf,&st)!=-1 && S_ISLNK(st.st_mode)){
strcpy (path,buf);
iter++;
}else{
if (str.is_empty()){
int skip = 0;
static const char *prefix = USR_LIB_ZONEINFO "/";
static int len = strlen(prefix);
if (strncmp(prefix,buf,len) == 0) skip = len;
str.setfrom (buf+skip);
}else{
unlink (path);
const char *pt = str.get();
if (pt[0] != '/'){
sprintf (buf,"%s/%s",USR_LIB_ZONEINFO,pt);
pt = buf;
}
symlink (pt,path);
}
break;
}
}
}
}
PUBLIC int DATETIME::edit ()
{
int ret = -1;
if (perm_rootaccess(MSG_U(P_CHGDATE,"correct the date and time"))){
DIALOG dia;
SSTRING year,month,mday,hour,minutes,seconds;
{
time_t t;
time (&t);
struct tm *tmt = localtime (&t);
month.setfrom (tmt->tm_mon+1);
year.setfrom (tmt->tm_year);
mday.setfrom (tmt->tm_mday);
hour.setfrom (tmt->tm_hour);
minutes.setfrom (tmt->tm_min);
seconds.setfrom (tmt->tm_sec);
}
SSTRING zone;
datetime_getsetcurzone (zone);
FIELD_COMBO * comb = dia.newf_combo (MSG_U(F_ZONE,"zone"),zone);
datetime_zonelst (comb);
dia.newf_chk (MSG_U(F_STORECMOS,"Store date in CMOS"),universal
,MSG_U(F_UNIVERSAL,"universal format(GMT)"));
dia.newf_str (MSG_U(F_GETDATE,"Get date from server(s)"),netdate);
dia.newf_title ("",MSG_U(T_TIME,"Time"));
dia.newf_str (MSG_U(F_HOUR,"Hour"),hour);
dia.newf_str (MSG_U(F_MINUTES,"Minutes"),minutes);
dia.newf_str (MSG_U(F_SECONDS,"Seconds"),seconds);
dia.newf_title ("",MSG_U(T_DATE,"Date"));
dia.newf_str (MSG_U(F_YEAR,"Year"),year);
dia.newf_str (MSG_U(F_MONTH,"Month"),month);
dia.newf_str (MSG_U(F_DAYOFMONTH,"Day of month"),mday);
if (dia.edit (MSG_U(T_DATETIME,"Workstation date & time")
,MSG_U(I_DATETIME
,"Fill this form to indicate how the workstation must\n"
"get its date and time\n")
,help_date.getpath(),0) == MENU_ACCEPT){
datetime_getsetcurzone (zone);
struct tm tmt;
tmt.tm_hour = hour.getval();
tmt.tm_min = minutes.getval();
tmt.tm_sec = seconds.getval();
tmt.tm_year = year.getval();
if (tmt.tm_year > 1900) tmt.tm_year -= 1900;
tmt.tm_mon = month.getval()-1;
tmt.tm_mday = mday.getval();
tmt.tm_isdst = -1;
save();
if (netdate.is_empty()){
time_t t = mktime (&tmt);
stime (&t);
}else{
getfromnet();
}
updatecmos();
ret = 0;
}
}
return ret;
}
PUBLIC void DATETIME::updatecmos()
{
netconf_system_if ("clock",universal ? "-w -u" : "-w");
}
/*
Get the date from CMOS
*/
PUBLIC int DATETIME::getfromcmos()
{
return netconf_system_if ("clock",universal ? "-s -u" : "-s");
}
/*
Get the current date and time from servers on the net.
This will be done only if configured.
Return -1 if any error.
Return 0 if ok or if it was not configured to do so.
*/
PUBLIC int DATETIME::getfromnet()
{
int ret = 0;
if (!netdate.is_empty()){
ret = netconf_system_if ("netdate",netdate.get());
if (ret == 0) updatecmos();
}
return ret;
}
int datetime_getfromnet()
{
DATETIME dt;
return dt.getfromnet();
}
int datetime_getfromcmos()
{
DATETIME dt;
return dt.getfromcmos();
}
int datetime_edit()
{
DATETIME dt;
return dt.edit();
}